package com.netCross.myapplication;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.SurfaceTexture;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.util.Size;
import android.view.Surface;
import android.view.TextureView;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class CameraDemo extends AppCompatActivity {
    TextureView mPreviewView;
    HandlerThread mHandlerThread;
    Handler mCaneraHandler;
    CameraManager manager;
    Size mPreviewSize;
    String mCameraId;
    CameraDevice mCameraDevice;
    CaptureRequest.Builder mCaptureRequestBuilder;
    CaptureRequest mcaptureRequest;
    CameraCaptureSession mCameraCaptureSessionm;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera_demo);
    }

    @Override
    protected void onResume() {
        super.onResume();
        startCameraThread();
        if (!mPreviewView.isAvailable()) {
            mPreviewView.setSurfaceTextureListener(mTextureListener);
        }else{
            startPreview();

        }

    }

    TextureView.SurfaceTextureListener mTextureListener = new TextureView.SurfaceTextureListener() {
        @RequiresApi(api = Build.VERSION_CODES.M)
        @Override
        public void onSurfaceTextureAvailable(@NonNull SurfaceTexture surface, int width, int height) {
            //当surfaceTexture 可用,设置相机参数,打开摄像头
            try {
                setupCamera(width, height);
            } catch (CameraAccessException e) {
                e.printStackTrace();
            }
            openCamera();
        }

        @Override
        public void onSurfaceTextureSizeChanged(@NonNull SurfaceTexture surface, int width, int height) {

        }

        @Override
        public boolean onSurfaceTextureDestroyed(@NonNull SurfaceTexture surface) {
            return false;
        }

        @Override
        public void onSurfaceTextureUpdated(@NonNull SurfaceTexture surface) {

        }
    };

    //开启摄像头线程
    private void startCameraThread() {
        mHandlerThread = new HandlerThread("CamerThread");
        mHandlerThread.start();
        mCaneraHandler = new Handler(mHandlerThread.getLooper());
    }

    //设置摄像头参数
    private void setupCamera(int width, int height) throws CameraAccessException {
        manager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
        //拿到摄像头id
        try {
            for (String cameraID : manager.getCameraIdList()) {
                CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID);
                Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
                if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
                    continue;
                }
                StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
                if (map != null) {
                    //找到摄像头能适配的最小分辨率
                    mPreviewSize = getOptimalSize(map.getOutputSizes(SurfaceTexture.class), width, height);

                }
                mCameraId = cameraID;
                break;
            }
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }
    }

    private Size getOptimalSize(Size[] sizeMap, int width, int height) {
        List<Size> sizeList = new ArrayList<Size>();
        for (Size option : sizeMap) {
            if (width > height) {
                if (option.getWidth() > width && option.getHeight() > height) {
                    sizeList.add(option);
                } else {
                    //竖屏情况
                    if (option.getWidth() > height && option.getHeight() > width) {
                        sizeList.add(option);
                    }
                }
            }
        }
        return sizeMap[0];
    }


    //打开摄像头
    @RequiresApi(api = Build.VERSION_CODES.M)
    private void openCamera() {
        String [] permissions = {Manifest.permission.CAMERA};
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
            this.requestPermissions(permissions,0);
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return;
        }
        try {
            manager.openCamera(mCameraId, mStateCallback, mCaneraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }

    }
    CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
        @Override
        public void onOpened(@NonNull CameraDevice camera) {
            mCameraDevice = camera;
            startPreview();
        }

        @Override
        public void onDisconnected(@NonNull CameraDevice camera) {
            mCameraDevice.close();
            mCameraDevice = null;
        }

        @Override
        public void onError(@NonNull CameraDevice camera, int error) {
            mCameraDevice.close();
            mCameraDevice = null;
        }
    };

    //开始预览
    private void startPreview(){
        //建立图像换缓冲区
        SurfaceTexture mSurfaceTexture = mPreviewView.getSurfaceTexture();
        mSurfaceTexture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());


        //先得到界面的显示图像
        Surface previewSurface  = new Surface(mSurfaceTexture);
        try {
            mCaptureRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
            mCaptureRequestBuilder.addTarget(previewSurface);
            //建立通道
            mCameraDevice.createCaptureSession(Arrays.asList(previewSurface), new CameraCaptureSession.StateCallback() {
                @Override
                public void onConfigured(@NonNull CameraCaptureSession session) {
                   mcaptureRequest =  mCaptureRequestBuilder.build();
                   mCameraCaptureSessionm = session;
                    try {
                        mCameraCaptureSessionm.setRepeatingRequest(mcaptureRequest,null,mCaneraHandler);
                    } catch (CameraAccessException e) {
                        e.printStackTrace();
                    }

                }

                @Override
                public void onConfigureFailed(@NonNull CameraCaptureSession session) {

                }
            }, mCaneraHandler);
        } catch (CameraAccessException e) {
            e.printStackTrace();
        }




    }
}